﻿/**
 * @author krozalski
 */

package hapi.math;

class Range {
	
	var start:Float;
	var end:Float;

	public function new(start, end) {
		this.start = start;
		this.end = end;
	}
	
	public dynamic function contains(x:Float) {
		return this.start <= x &&  x <= this.end;
	}
	
	function containsWithoutStart(x:Float) {
		return this.start < x &&  x <= this.end;
	}
	
	function containsWithoutEnd(x:Float) {
		return this.start <= x &&  x < this.end;
	}
	
	function containsWithoutStartOrEnd(x:Float) {
		return this.start < x &&  x < this.end;
	}
	
	public static function leftOpen( start, end ) {
		var r = new Range(start, end);
		r.contains = r.containsWithoutStart;
	}
	
	public static function rightOpen( start, end ) {
		var r = new Range(start, end);
		r.contains = r.containsWithoutEnd;
		return r;
	}
	
	public static function lessThan( value, ?containsValue:Bool=false ) {
		var r = new Range(Math.NEGATIVE_INFINITY, value);
		if (!containsValue) {
			r.contains = r.containsWithoutEnd;
		}
		return r;
	}
	
	public static function moreThan( value, ?containsValue:Bool=false ) {
		var r = new Range(value, Math.POSITIVE_INFINITY);
		if (!containsValue) {
			r.contains = r.containsWithoutStart;
		}
		return r;
	}
	
	public static function open( start, end ) {
		var r = new Range(start, end);
		r.contains = r.containsWithoutStartOrEnd;
		return r;
	}
	
	public function isLeftOpen() {
		return contains(this.start);
	}
	
	public function isRightOpen() {
		return contains(this.end);
	}
	
	public function toString() {
		var buf = new StringBuf();
		buf.add(isLeftOpen()? "(" : "<");
		buf.add(start + ", " + end);
		buf.add(isRightOpen()? ")" : ">");
		return buf.toString();
	}
}